package com.virtual.repository.common.criteria;

import com.virtual.repository.common.operators.CriteriaOperator;
import com.virtual.repository.common.operators.LogicalOperator;

/**
 * A selection criterion for the database statement.
 * @author Zielony
 * @version 1.0
 */
public class Criterion implements Cloneable {
	/**
	 * The property of the treated object on which the criterion is set.
	 */
	private String property;
	
	/**
	 * The operator expressing the criterion.
	 */
	private CriteriaOperator operator = null;
	
	/**
	 * The value determining the criterion.
	 */
	private Object value;
	
	/**
	 * The operator joining the criterion with the following one or closing the statement.
	 */
	private LogicalOperator prefixOperator = null;
	
	/**
	 * Builds the criterion without joining it with any other one.
	 * @param property the property of the treated object on which the criterion is set.
	 * @param operator the operator expressing the criterion.
	 * @param value the value determining the criterion.
	 */
	public Criterion(String property, CriteriaOperator operator, Object value) {
		this.property = property;
		this.operator = operator;
		this.value = value;
	}
	
	/**
	 * Builds the criterion in the general way.
	 * @param property the property of the treated object on which the criterion is set.
	 * @param operator the operator expressing the criterion.
	 * @param value the value determining the criterion.
	 * @param postfixOperator the operator joining the criterion with the following one or closing the statement.
	 */
	public Criterion(LogicalOperator prefixOperator, String property, CriteriaOperator operator, Object value) {
		this(property, operator, value);
		this.prefixOperator = prefixOperator;
	}
	
	/**
	 * Gets: the property of the treated object on which the criterion is set.
	 * @return the property of the treated object on which the criterion is set.
	 */
	public String getProperty()  {
		return property;
	}
	
	public void setProperty(String property)  {
		//used by QueryManager
		this.property = property;
	}
	
	/**
	 * Gets: the operator expressing the criterion.
	 * @return the operator expressing the criterion.
	 */
	public CriteriaOperator getCriteriaOperator() {
		return operator;
	}
	
	/**
	 * Gets: the value determining the criterion.
	 * @return the value determining the criterion.
	 */
	public Object getValue() {
		return value;
	}
	
	/**
	 * Gets: the operator joining the criterion with the following one or closing the statement.
	 * @return the operator joining the criterion with the following one or closing the statement.
	 */
	public LogicalOperator getPrefixOperator() {
		return prefixOperator;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		String result = " " + property + " " + operator + " " + value;
		
		if(prefixOperator != null) {
			result  = " " + prefixOperator + result;
		}
		
		return result;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public Criterion clone() throws CloneNotSupportedException {
		Criterion cloned = (Criterion)super.clone();
		
		/*
		 * Copying the state to the cloned instance. 
		 */
		cloned.operator = operator;
		cloned.prefixOperator = prefixOperator;
		cloned.property = property;
		cloned.value = value;
		
		return cloned;
	}
}